package util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.StringTokenizer;

import model.BacSi;
import model.BaiViet;
import model.Benh;
import model.DiaDiemYTe;
import model.GenerallyObject;
import model.LoaiBenh;
import model.LoaiThuoc;
import model.ThietBiYTe;
import model.ThongTinDB;
import model.Thuoc;

import org.hibernate.Session;

import dao.DAOFactory;
import dao.ThongTinDBDAO;
import dao.hibernate.HibernateDAOFactory;

public class Util {
	private static DAOFactory daoFactory = DAOFactory.instance(HibernateDAOFactory.class);
	private static ThongTinDBDAO thongTinDBDAO = daoFactory.getThongTinDBDAO();
	private static Session session = HibernateUtil.getCurrentSession();
	
	//Current directory is "bin" in tomcat
	public static String SQLITE_DB_FOLDER = "../webapps/HealthSystem_Core/db/sqlite/";
	public static String SQLITE_DB_FILENAME = "hethongyte.db";
	
//	public static String getJarFolder() {
//		return "db/sqlite";
//	  }
	
//	public static String getJarFolder() {
//	    // get name and path
//	    String name = Util.class.getName().replace('.', '/');
//	    name = Util.class.getResource("/" + name + ".class").toString();
//	    // remove junk
//	    name = name.substring(0, name.indexOf(".jar"));
//	    name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');
//	    // remove escape characters
//	    String s = "";
//	    for (int k=0; k<name.length(); k++) {
//	      s += name.charAt(k);
//	      if (name.charAt(k) == ' ') k += 2;
//	    }
//	    // replace '/' with system separator char
//	    return s.replace('/', File.separatorChar);
//	  }
	
	/**
	 * @return String format of a date (Example: 20110430123000 means 12:30:00 30/04/2011)
	 */
	public static String getCurrentDateString(){
		Calendar calendar = new GregorianCalendar();
		String month = (calendar.get(Calendar.MONTH) + 1) < 10 ? "0" + (calendar.get(Calendar.MONTH) + 1) : (calendar.get(Calendar.MONTH) + 1) + "";
		String day = calendar.get(Calendar.DATE) < 10 ? "0" + calendar.get(Calendar.DATE) : calendar.get(Calendar.DATE) + "";
		String hour = calendar.get(Calendar.HOUR_OF_DAY) < 10 ? "0" + calendar.get(Calendar.HOUR_OF_DAY) : calendar.get(Calendar.HOUR_OF_DAY) + "";
		String minute = calendar.get(Calendar.MINUTE) < 10 ? "0" + calendar.get(Calendar.MINUTE) : calendar.get(Calendar.MINUTE) + "";
		String second = calendar.get(Calendar.SECOND) < 10 ? "0" + calendar.get(Calendar.SECOND) : calendar.get(Calendar.SECOND) + "";
		return calendar.get(Calendar.YEAR) + month + day + hour + minute + second;
	}
	
	/**
     * Returns the contents of the file in a byte array
     * @param file File this method should read
     * @return byte[] Returns a byte[] array of the contents of the file
     */
    public static byte[] getBytesFromFile(File file) throws IOException {

        InputStream is = new FileInputStream(file);
        // Get the size of the file
        long length = file.length();

        /*
         * You cannot create an array using a long type. It needs to be an int
         * type. Before converting to an int type, check to ensure that file is
         * not loarger than Integer.MAX_VALUE;
         */
        if (length > Integer.MAX_VALUE) {
            System.out.println("File is too large to process");
            return null;
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[(int)length];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while ( (offset < bytes.length)
                &&
                ( (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) ) {

            offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }

        is.close();
        return bytes;

    }
    
    /**
     * Returns the date string
     * @param Date
     * @return Date string in format "yyyy-MM-dd HH:mm:ss"
     */
    public static String getDateString(Date date){
    	Calendar calendar = new GregorianCalendar();
    	calendar.setTime(date);
    	int day = calendar.get(Calendar.DATE);
    	String dayStr = day < 10 ? "0" + day : day + "";
    	int month = calendar.get(Calendar.MONTH) + 1;
    	String monthStr = month < 10 ? "0" + month : month + "";
    	int year = calendar.get(Calendar.YEAR);
    	String yearStr = year < 10 ? "0" + year : year + "";
    	int hour = calendar.get(Calendar.HOUR_OF_DAY);
    	String hourStr = hour < 10 ? "0" + hour : hour + "";
    	int minute = calendar.get(Calendar.MINUTE);
    	String minuteStr = minute < 10 ? "0" + minute : minute + "";
    	int second = calendar.get(Calendar.SECOND);
    	String secondStr = second < 10 ? "0" + second : second + "";
    	
    	return yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
    }
    
    public static void updateDatabaseVersion(String ghiChu){
    	session = HibernateUtil.getCurrentSession();
    	session.getTransaction().begin();
    	ThongTinDB thongTinDB = thongTinDBDAO.findById(1l, false);
    	if (thongTinDB != null) {
    		thongTinDB.setPhienBan(thongTinDB.getPhienBan() + 1);
    		thongTinDB.setNgayCapNhat(new Date());
    		thongTinDB.setGhiChu(ghiChu);
    		session.saveOrUpdate(thongTinDB);
    	}
    	session.getTransaction().commit();
    }
    
    public static String dateTimeToString(Date date) {
    	Calendar calendar = new GregorianCalendar();
    	calendar.setTime(date);
    	int day = calendar.get(Calendar.DATE);
    	String dayStr = day < 10 ? "0" + day : day + "";
    	int month = calendar.get(Calendar.MONTH) + 1;
    	String monthStr = month < 10 ? "0" + month : month + "";
    	int year = calendar.get(Calendar.YEAR);
    	String yearStr = year < 10 ? "0" + year : year + "";
    	int hour = calendar.get(Calendar.HOUR_OF_DAY);
    	String hourStr = hour < 10 ? "0" + hour : hour + "";
    	int minute = calendar.get(Calendar.MINUTE);
    	String minuteStr = minute < 10 ? "0" + minute : minute + "";
        return hourStr + ":" + minuteStr + ", ngày " + dayStr + "/" + monthStr + "/" + yearStr;
    }
    
    //Convert string in format "dd/mm/yyyy" to Date
    public static Date convertStringToDate(String dateString){
    	StringTokenizer tokenizer = new StringTokenizer(dateString, "/");
    	int date = Integer.parseInt(tokenizer.nextToken());
    	int month = Integer.parseInt(tokenizer.nextToken());
    	int year = Integer.parseInt(tokenizer.nextToken());
    	GregorianCalendar calendar = new GregorianCalendar();
    	calendar.set(year, month - 1, date);
    	return calendar.getTime();
    }
	
    /*-------------------------------------------------------------------*/
 // convert from list BacSi to list GenerallyObject
	public static ArrayList<GenerallyObject> convertBacSiListToGenerallyObjectList(
			List<BacSi> listBacSi) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listBacSi.size(); i++) {
			BacSi bs = listBacSi.get(i);
			String loai = "BacSi";
			long id = bs.getIdChuDe();
			String ten = bs.getTenChuDe();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// convert from list LoaiBenh to list GenerallyObject
	public static ArrayList<GenerallyObject> convertLoaiBenhListToGenerallyObjectList(
			List<LoaiBenh> listLoaiBenh) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listLoaiBenh.size(); i++) {
			LoaiBenh b = listLoaiBenh.get(i);
			String loai = "LoaiBenh";
			long id = b.getIdLoaiBenh();
			String ten = b.getTenLoaiBenh();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// convert from list LoaiThuoc to list GenerallyObject
	public static ArrayList<GenerallyObject> convertLoaiThuocListToGenerallyObjectList(
			List<LoaiThuoc> listLoaiThuoc) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listLoaiThuoc.size(); i++) {
			LoaiThuoc b = listLoaiThuoc.get(i);
			String loai = "LoaiThuoc";
			long id = b.getIdLoaiThuoc();
			String ten = b.getTenLoaiThuoc();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// convert from list Benh to list GenerallyObject
	public static ArrayList<GenerallyObject> convertBenhListToGenerallyObjectList(
			List<Benh> listBenh) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listBenh.size(); i++) {
			Benh b = listBenh.get(i);
			String loai = "Benh";
			long id = b.getIdChuDe();
			String ten = b.getTenChuDe();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// convert from list Thuoc to list GenerallyObject
	public static ArrayList<GenerallyObject> convertThuocListToGenerallyObjectList(
			List<Thuoc> listThuoc) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listThuoc.size(); i++) {
			Thuoc b = listThuoc.get(i);
			String loai = "Thuoc";
			long id = b.getIdChuDe();
			String ten = b.getTenChuDe();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// convert from list ThietBiYTe to list GenerallyObject
	public static ArrayList<GenerallyObject> convertThietBiYTeListToGenerallyObjectList(
			List<ThietBiYTe> listThietBiYTe) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listThietBiYTe.size(); i++) {
			ThietBiYTe b = listThietBiYTe.get(i);
			String loai = "ThietBiYTe";
			long id = b.getIdChuDe();
			String ten = b.getTenChuDe();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// convert from list BaiViet to list GenerallyObject
	public static ArrayList<GenerallyObject> convertBaiVietListToGenerallyObjectList(
			List<BaiViet> listBaiViet) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listBaiViet.size(); i++) {
			BaiViet b = listBaiViet.get(i);
			String loai = "BaiViet";
			long id = b.getIdBaiViet();
			String ten = b.getTieuDe();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// convert from list DiaDiemYTe to list GenerallyObject
	public static ArrayList<GenerallyObject> convertDiaDiemYTeListToGenerallyObjectList(
			List<DiaDiemYTe> listDiaDiemYTe) {
		ArrayList<GenerallyObject> list = new ArrayList<GenerallyObject>();
		for (int i = 0; i < listDiaDiemYTe.size(); i++) {
			DiaDiemYTe b = listDiaDiemYTe.get(i);
			String loai = "DiaDiemYTe";
			long id = b.getIdChuDe();
			String ten = b.getTenChuDe();
			GenerallyObject o = new GenerallyObject(loai, id, ten);
			list.add(o);
		}
		return list;
	}

	// AND 2 list of BacSi
	public static List<BacSi> retainAllBacSi(List<BacSi> list1,
			List<BacSi> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<BacSi> result = new ArrayList<BacSi>();
			for (int i = 0; i < list1.size(); i++) {
				BacSi bs = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (bs.getIdChuDe() == list2.get(j).getIdChuDe()) {
						result.add(bs);
						break;
					}
				}
			}
			return result;
		}
	}

	// AND 2 list of BaiViet
	public static List<BaiViet> retainAllBaiViet(List<BaiViet> list1,
			List<BaiViet> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<BaiViet> result = new ArrayList<BaiViet>();
			for (int i = 0; i < list1.size(); i++) {
				BaiViet bv = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (bv.getIdBaiViet() == list2.get(j).getIdBaiViet()) {
						result.add(bv);
						break;
					}
				}
			}
			return result;
		}
	}

	// AND 2 list of LoaiBenh
	public static List<LoaiBenh> retainAllLoaiBenh(List<LoaiBenh> list1,
			List<LoaiBenh> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<LoaiBenh> result = new ArrayList<LoaiBenh>();
			for (int i = 0; i < list1.size(); i++) {
				LoaiBenh lb = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (lb.getIdLoaiBenh() == list2.get(j).getIdLoaiBenh()) {
						result.add(lb);
						break;
					}
				}
			}
			return result;
		}
	}

	// AND 2 list of LoaiThuoc
	public static List<LoaiThuoc> retainAllLoaiThuoc(List<LoaiThuoc> list1,
			List<LoaiThuoc> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<LoaiThuoc> result = new ArrayList<LoaiThuoc>();
			for (int i = 0; i < list1.size(); i++) {
				LoaiThuoc lt = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (lt.getIdLoaiThuoc() == list2.get(j).getIdLoaiThuoc()) {
						result.add(lt);
						break;
					}
				}
			}
			return result;
		}
	}

	// AND 2 list of Benh
	public static List<Benh> retainAllBenh(List<Benh> list1, List<Benh> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<Benh> result = new ArrayList<Benh>();
			for (int i = 0; i < list1.size(); i++) {
				Benh b = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (b.getIdChuDe() == list2.get(j).getIdChuDe()) {
						result.add(b);
						break;
					}
				}
			}
			return result;
		}
	}

	// AND 2 list of Thuoc
	public static List<Thuoc> retainAllThuoc(List<Thuoc> list1,
			List<Thuoc> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<Thuoc> result = new ArrayList<Thuoc>();
			for (int i = 0; i < list1.size(); i++) {
				Thuoc t = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (t.getIdChuDe() == list2.get(j).getIdChuDe()) {
						result.add(t);
						break;
					}
				}
			}
			return result;
		}
	}

	// AND 2 list of ThietBiYTe
	public static List<ThietBiYTe> retainAllThietBiYTe(List<ThietBiYTe> list1,
			List<ThietBiYTe> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<ThietBiYTe> result = new ArrayList<ThietBiYTe>();
			for (int i = 0; i < list1.size(); i++) {
				ThietBiYTe t = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (t.getIdChuDe() == list2.get(j).getIdChuDe()) {
						result.add(t);
						break;
					}
				}
			}
			return result;
		}
	}

	// AND 2 list of DiaDiemYTe
	public static List<DiaDiemYTe> retainAllDiaDiemYTe(List<DiaDiemYTe> list1,
			List<DiaDiemYTe> list2) {
		if (list1 == null)
			return list2;
		else if (list2 == null)
			return list1;
		else {
			List<DiaDiemYTe> result = new ArrayList<DiaDiemYTe>();
			for (int i = 0; i < list1.size(); i++) {
				DiaDiemYTe d = list1.get(i);
				for (int j = 0; j < list2.size(); j++) {
					if (d.getIdChuDe() == list2.get(j).getIdChuDe()) {
						result.add(d);
						break;
					}
				}
			}
			return result;
		}
	}

	public static void main(String[] args) {
		 updateDatabaseVersion("Cập nhật thông tin đầy đủ hơn");
		// System.out.println(convertStringToDate("30/04/1989"));
//		GenerallyObject o1 = new GenerallyObject("1", 1, "1");
//		GenerallyObject o2 = new GenerallyObject("2", 2, "2");
//		GenerallyObject o3 = new GenerallyObject("3", 3, "3");
//		GenerallyObject o4 = new GenerallyObject("4", 4, "4");
//		List<GenerallyObject> list1 = new ArrayList<GenerallyObject>();
//		list1.add(o1);
//		list1.add(o3);
//		list1.add(o4);
//
//		List<GenerallyObject> list2 = new ArrayList<GenerallyObject>();
//		list2.add(o1);
//		list2.add(o2);
//		list2.add(o3);
//
//		list1.retainAll(list2);
//		for (GenerallyObject generallyObject : list1) {
//			System.out.println(generallyObject.getId());
//		}
	}
}
